出处:掘金

原作者:ErpanOmer


在前端性能优化中,Total Blocking Time (TBT) 是一个不容忽视的重要指标。它是衡量网页交互性能的关键指标之一,尤其对单页应用和动态内容页面尤为重要。本文将通过理论解析、代码示例以及优化策略,为您全面剖析 TBT 的本质和优化方法

什么是 Total Blocking Time?

Total Blocking Time 表示从页面首次开始渲染内容到用户可交互之间,被阻塞时间的总和。具体来说,它计算的是长任务(任务执行时间超过 50 ms)阻塞主线程的时间

核心概念

公式

TBT = ∑(每个任务耗时 - 50ms) # 仅计算超过 50ms 的任务

为什么 TBT 重要?

如何测量 TBT?

const observer = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
        if (entry.duration > 50) {
            console.log(`Long Task Detected: ${entry.duration}ms`);
        }
    }
});

observer.observe({ type: 'longtask', buffered: true });

TBT 的常见问题

JavaScript 执行时间过长

问题:JavaScript 阻塞主线程,导致用户无法进行操作

示例

// 一个耗时过长的同步任务
function heavyTask() {
    const start = Date.now();
    while (Date.now() - start < 200) {
        // 模拟长任务
    }
}
heavyTask();

优化方法:将长任务拆分为小任务,通过 setTimeout 或 requestIdleCallback 优化

function heavyTaskOptimized() {
    let start = 0;
    const chunk = 20; // 每次处理 20ms

    function processChunk() {
        const now = Date.now();
        while (Date.now() - now < chunk) {
            // 模拟部分任务
            start++;
        }

        if (start < 1000) {
            setTimeout(processChunk, 0); // 将剩余任务推迟到下一个事件循环
        }
    }
    processChunk();
}
heavyTaskOptimized();

过度渲染导致阻塞

问题:频繁的 DOM 操作占用主线程

示例

// 创建 1000 个 DOM 元素
for (let i = 0; i < 1000; i++) {
    const div = document.createElement('div');
    div.textContent = `Element ${i}`;
    document.body.appendChild(div);
}

优化方法:使用 DocumentFragment 或虚拟 DOM 减少渲染阻塞

const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
    const div = document.createElement('div');
    div.textContent = `Element ${i}`;
    fragment.appendChild(div);
}
document.body.appendChild(fragment);

大量 CSS 计算和重绘

问题:复杂的 CSS 样式或动画阻塞渲染

示例

.heavy-animation {
    animation: heavyTask 10s linear infinite;
}

@keyframes heavyTask {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

优化方法:尽量使用 transform 和 opacity,避免触发布局和重绘

.optimized-animation {
    animation: optimizedTask 10s linear infinite;
}

@keyframes optimizedTask {
    0% { transform: translateX(0); }
    100% { transform: translateX(100px); }
}

优化 TBT 的最佳实践

  1. 减少长任务
  2. 延迟加载资源
  3. 优化第三方脚本
  4. 使用高效的数据处理
  5. CSS 和动画优化

工具推荐

  1. Lighthouse:Google 官方提供的性能分析工具,可以生成全面的 TBT 报告
  2. WebPageTest:高级分析工具,适合测试复杂场景
  3. Perfume.js:一个前端性能监控工具,支持自动计算 TBT 和其他指标
import { Perfume } from 'perfume.js';
const perfume = new Perfume({ firstPaint: true, timeToInteractive: true });
console.log(`TBT: ${perfume.totalBlockingTime}`);

总结

TBT 是一个反映网页交互性能的重要指标,它不仅影响用户体验,还影响 SEO 和核心 Web 指标的评分。在现代 Web 开发中,通过优化 JavaScript 执行、减少阻塞操作和充分利用异步技术,可以显著降低 TBT 提升性能

优化 TBT 的过程,既是对技术能力的考验,也是提升用户体验的关键一步。无论是小型项目还是复杂应用,专注于优化 TBT,都会为用户带来更流畅的使用体验